package Java.view.game.dian21;

import Java.utils.JDBC;
import Java.view.Common.GameFX;
import Java.view.game.doudizhurule.Common;
import domain.User;
import domain.User1;
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.awt.*;
import java.io.*;
import java.net.Socket;
import java.sql.Connection;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Objects;

public class dian21FX extends Application {
    public static Socket socket;
    public User1 player1=new User1();
    public static int flag1=0;

    public static int flag2=0;
    static {
        try {
            socket = new Socket("127.0.0.1", 8848);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    boolean flag=false;
    int buyao=0;
    private static BufferedWriter writer;
    private static BufferedReader reader;
    private static final int WIDTH = 830;
    private static final int HEIGHT = 600;
    private Pane root;
    //牌堆 玩家和电脑的牌
    private Socket connection;//和服务器进行连接
    private final ArrayList<Poker> pokerList = new ArrayList<>();
    private final ArrayList<Poker> computer = new ArrayList<>();
    private final ArrayList<Poker> player = new ArrayList<>();
    String usernamelist[]=new String[2];
    ArrayList<String> datalist;
    //按钮
    private Button begin; //开始游戏
    private Button reset; //重新开始
    private Button get; //要牌
    private Button stop; //停牌
    private Button back; //返回
    private ImageView backgroundView;
    private ImageView  ruleView;
    //玩家名
    private Label playerName;
    private Label computerName;
    private String username;
    User user;
    //牌的索引
    private int index = 4;
    //玩家是否需要牌
    private boolean playerNeed = true;
    private boolean computerNeed = true;
    //牌正面朝上
    public int turn;
    public int i;
    public int now=1;
    //牌堆初始位置
    Point cardPoint = new Point(357, 15);

    public dian21FX(User user, int i) {
        this.username = user.getUsername();
        this.user = user;
        this.i=i;
    }
    @Override
    public void start(Stage primaryStage) throws IOException {
        if (i == 1) {
            primaryStage.setTitle("21点单机");
            primaryStage.getIcons().add(new Image("file:src/image/dizhu.png"));
            root = new Pane();
            //初始化组件
            initializeComponents();
            //设置主界面大小
            primaryStage.setScene(new Scene(root, WIDTH, HEIGHT));
            primaryStage.show();
            //初始化牌堆，洗牌
            initCard();

        }else{
            primaryStage.setTitle("21点联机");
            primaryStage.getIcons().add(new Image("file:src/image/dizhu.png"));
            root = new Pane();
            //初始化组件
            initializeComponents1();
            primaryStage.setScene(new Scene(root, WIDTH, HEIGHT));
            primaryStage.show();
            String message = "login2#" + user.getUsername() + "#" + user.getPassword() + "$";
            //设置主界面大小
            socket = new Socket("127.0.0.1", 8848);

            writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            try {
                writer.write(message);
                writer.newLine();
                writer.flush();

            } catch (IOException e) {
                System.out.println("客户发送登录信息时出现异常");
                throw new RuntimeException(e);
            }
            //接受玩家序列
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String usernames = in.readLine();
            System.out.println(usernames);
            usernamelist = usernames.split(" ");

            BufferedReader in1 = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String usernamess = in1.readLine();
            System.out.println(usernamess);
            //接受初始牌
            if (usernamess.endsWith("$")) {
                player1.playerID= Integer.parseInt(usernamess.substring(10,11));
                usernamess = usernamess.substring(12, usernamess.length() - 1);

            }
            datalist = new ArrayList<>();
            String[] splitArray = usernamess.split(" ");
            Collections.addAll(datalist, splitArray);
            for(int i=0;i< datalist.size();i++){
                System.out.println(datalist.get(i));
            }
            //初始化牌堆，洗牌
            initCard();
        }

    }
    private void receiveMessage() {
        //flag1和flag2分别表示玩家1和2是否已经停牌
        if(flag1==1){
            //now代表目前玩家
            now=2;
        }
        if(flag2==1){
            now=1;
        }
        System.out.println("now"+now);
        while(true) {
            if (now == player1.playerID) {
                get.setVisible(true);
                stop.setVisible(true);
            } else {
                get.setVisible(false);
                stop.setVisible(false);
            }

            try {
                BufferedReader in5 = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String e = null;
                while (e == null|| e.isEmpty()) {
                    e = in5.readLine();
                    if (e == null || e.isEmpty()) {
                        // 如果 e 是空字符串或者 null，跳过此次处理
                        continue;
                    }
                    if (e.endsWith("$")) {
                        e = e.substring(0, e.length() - 1);

                    }
                    String finalE = e;
                    Platform.runLater(() -> {
                        System.out.println(finalE);
                        ArrayList<String> datalist1 = new ArrayList<>();
                        String[] splitArray = finalE.split("#");
                        Collections.addAll(datalist1, splitArray);
                        System.out.println(datalist1);
                        processReceivedMessage(datalist1);

                    });
                }

            } catch (Exception ex) {
                ex.printStackTrace();
            }

        }
//
    }

    private void processReceivedMessage(ArrayList<String> datalist) {
        if(new Integer(datalist.get(0))==3){
            showAlert(Alert.AlertType.INFORMATION, "结果", null, "平局！");
        }else {
            if (player1.playerID == new Integer(datalist.get(0))) {
                System.out.println(1);
                //点停牌发送jump
                if (datalist.get(1).equals("jump")) {
                    if (now == 1) {
                        now = 2;
                    } else {
                        now = 1;
                    }
                    System.out.println("现在轮到" + now);
                    if (player1.playerID == 1) {
                        flag1 = 1;
                    } else {
                        flag2 = 1;
                    }
                    new Thread(this::receiveMessage).start();
                } else if (datalist.get(1).equals("ok")) {
                    showAlert(Alert.AlertType.INFORMATION, "结果", null, "恭喜你赢了！");
                } else if (datalist.get(1).equals("end")) {
                    showAlert(Alert.AlertType.INFORMATION, "结果", null, "抱歉您输了！");
                } else//前面要牌
                {
                    if (now == 1) {
                        now = 2;
                    } else {
                        now = 1;
                    }

                    System.out.println("现在轮到" + now);
                    Poker poker = new Poker(this, panduan(datalist.get(1)), panValue(panduan(datalist.get(1))), true);
                    player.add(poker);
                    root.getChildren().add(poker);
                    Tool.move(poker, cardPoint, new Point(510 + 30 * (player.size() - 1), 225));
                    poker.turnFront();
                    new Thread(this::receiveMessage).start();

                }
            } else //收到的消息是对面的消息
            {

                if (datalist.get(1).equals("jump")) {
                    if (player1.playerID == 1) {
                        flag2 = 1;
                    } else {
                        flag1 = 1;
                    }
                    buyao++;
                    new Thread(this::receiveMessage).start();
                } else if (datalist.get(1).equals("ok")) {
                    showAlert(Alert.AlertType.INFORMATION, "结果", null, "抱歉你输了！");
                } else if (datalist.get(1).equals("end")) {
                    showAlert(Alert.AlertType.INFORMATION, "结果", null, "恭喜你赢了！");
                } else {
                    now = player1.playerID;
                    System.out.println("现在轮到" + now);
                    Poker poker = new Poker(this, panduan(datalist.get(1)), panValue(panduan(datalist.get(1))), true);
                    computer.add(poker);
                    Tool.move(poker, cardPoint, new Point(75 + 30 * (computer.size() - 1), 225));
                    poker.toFront();

                    new Thread(this::receiveMessage).start();
                }
            }
        }

    }

    private void initializeComponents1() {

        //斗牛规则
        Image ruleImg = new Image("file:src/image/21点规则.png");
        ruleView = new ImageView(ruleImg);
        ruleView.setFitWidth(WIDTH);
        ruleView.setFitHeight(HEIGHT);
        root.getChildren().add(ruleView);

        //背景
        Image backgroundImg = new Image("file:src/image/背景2.jpg");
        backgroundView = new ImageView(backgroundImg);
        backgroundView.setFitWidth(WIDTH);
        backgroundView.setFitHeight(HEIGHT);
        backgroundView.setVisible(false); // 初始时隐藏背景图片
        root.getChildren().add(backgroundView);



        //开始按钮
        begin = createButton("file:src/image/game/开始游戏.png", 340, 470);
        begin.setOnAction(event -> {
            try {
                startGame1();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
        //重置按钮
        reset = createButton("file:src/image/game/重新开始.png", 340, 470);
        reset.setVisible(false);//不可见
        reset.setOnAction(event -> resetGame());
        //要牌按钮
        get = createButton("file:src/image/game/要牌.png", 155, 470);
        get.setVisible(false);//不可见
        get.setOnAction(event -> getCard1());
        //停牌按钮
        stop = createButton("file:src/image/game/停牌.png", 565, 470);
        stop.setVisible(false);//不可见
        stop.setOnAction(event -> stopGetCard1());
        //返回按钮
        back = createButton("file:src/image/返回.png", 20, 20);
        back.setOnAction(event -> goBack());
        //玩家名字标签
        playerName = new Label(username);
        playerName.setFont(Font.font("黑体", 20));
        playerName.setTextFill(Color.BLACK);
        playerName.setLayoutX(550);
        playerName.setLayoutY(190);
        playerName.setVisible(false);//不可见
        //电脑1名字标签
        if(player1.playerID==1) {
            computerName = new Label("888");
            computerName.setFont(Font.font("黑体", 20));
            computerName.setTextFill(Color.BLACK);
            computerName.setLayoutX(135);
            computerName.setLayoutY(190);
            computerName.setVisible(false);//不可见
            //添加组件到主界面
            root.getChildren().addAll(begin, reset, playerName, computerName, get, stop, back);
        }else{
            computerName = new Label("888");
            computerName.setFont(Font.font("黑体", 20));
            computerName.setTextFill(Color.BLACK);
            computerName.setLayoutX(135);
            computerName.setLayoutY(190);
            computerName.setVisible(false);//不可见
            //添加组件到主界面
            root.getChildren().addAll(begin, reset, playerName, computerName, get, stop, back);
        }
    }

    private void stopGetCard1() {
        flag=true;
        player1.sendDataToServer("playcard1#" + player1.playerID +"#不要"+ "$");
        System.out.println("playcard1#" + player1.playerID + "$");
    }

    private void getCard1() {
        flag=true;
        player1.sendDataToServer("playcard1#" + player1.playerID +"#要"+ "$");
        System.out.println("playcard1#" + player1.playerID + "$");
    }

    //初始化组件
    private void initializeComponents() {

        //斗牛规则
        Image ruleImg = new Image("file:src/image/21点规则.png");
        ruleView = new ImageView(ruleImg);
        ruleView.setFitWidth(WIDTH);
        ruleView.setFitHeight(HEIGHT);
        root.getChildren().add(ruleView);

        //背景
        Image backgroundImg = new Image("file:src/image/背景2.jpg");
        backgroundView = new ImageView(backgroundImg);
        backgroundView.setFitWidth(WIDTH);
        backgroundView.setFitHeight(HEIGHT);
        backgroundView.setVisible(false); // 初始时隐藏背景图片
        root.getChildren().add(backgroundView);



        //开始按钮
        begin = createButton("file:src/image/game/开始游戏.png", 340, 470);
        begin.setOnAction(event -> {
            startGame();
        });
        //重置按钮
        reset = createButton("file:src/image/game/重新开始.png", 340, 470);
        reset.setVisible(false);//不可见
        reset.setOnAction(event ->{
                Platform.runLater(() -> resetGame());
        });
        //要牌按钮
        get = createButton("file:src/image/game/要牌.png", 155, 470);
        get.setVisible(false);//不可见
        get.setOnAction(event -> getCard());
        //停牌按钮
        stop = createButton("file:src/image/game/停牌.png", 565, 470);
        stop.setVisible(false);//不可见
        stop.setOnAction(event -> {
            Platform.runLater(() -> stopGetCard());
        });
        //返回按钮
        back = createButton("file:src/image/返回.png", 20, 20);
        back.setOnAction(event -> goBack());
        //玩家名字标签
        playerName = new Label(username);
        playerName.setFont(Font.font("黑体", 20));
        playerName.setTextFill(Color.BLACK);
        playerName.setLayoutX(550);
        playerName.setLayoutY(190);
        playerName.setVisible(false);//不可见
        //电脑1名字标签
        computerName = new Label("庄家");
        computerName.setFont(Font.font("黑体", 20));
        computerName.setTextFill(Color.BLACK);
        computerName.setLayoutX(135);
        computerName.setLayoutY(190);
        computerName.setVisible(false);//不可见
        //添加组件到主界面
        root.getChildren().addAll(begin,reset, playerName, computerName, get, stop, back);
    }
    //返回
    private void goBack() {
        new GameFX(user).start(new Stage());
        ((Stage) back.getScene().getWindow()).close();
    }
    //按钮样式
    private Button createButton(String imagePath, int x, int y) {
        Button button = new Button();
        Image image = new Image(imagePath);
        ImageView imageView = new ImageView(image);
        button.setGraphic(imageView);
        button.setLayoutX(x);
        button.setLayoutY(y);
        button.setStyle("-fx-background-color: transparent; -fx-border-width: 0;");
        return button;
    }
    //初始化牌堆
    private void initCard() {


        for (int i = 0; i <= 51; i++) {
            String name = String.valueOf(i);
            Poker poker = new Poker(this, name, i, false);
            //牌堆的初始位置
            poker.setTranslateX(357);
            poker.setTranslateY(15);
            pokerList.add(poker);
            root.getChildren().add(poker); // 添加到场景图中
        }
        //洗牌
        Collections.shuffle(pokerList);
    }
    private void startGame1() throws IOException {

        //移除规则介绍
        if (root != null && ruleView != null && backgroundView != null) {
            root.getChildren().remove(ruleView);
            backgroundView.setVisible(true);
        } else {
            System.out.println("组件未正确初始化！");
        }

        //发牌
        for (int i = 0; i < 4; i++) {

            if (i >1) {
                Poker poker = pokerList.get(i);
                computer.add(poker);
                Tool.move(poker,cardPoint,new Point(75 + 30 * (computer.size() -1), 225));
                poker.toFront();
            } else {
                System.out.println(panduan(datalist.get(i)));
                Poker poker = new Poker(this, panduan(datalist.get(i)), i, false);
                player.add(poker);
                root.getChildren().add(poker);
                Tool.move(poker,cardPoint,new Point(510 + 30 * (player.size()-1), 225));
                poker.turnFront();
            }
//            poker.toFront(); // 牌置顶
        }
        // 显示按钮
        get.setVisible(true);
        stop.setVisible(true);
        begin.setVisible(false);
        //显示玩家名
        playerName.setVisible(true);
        computerName.setVisible(true);
        System.out.println("当前玩家" + now);



        new Thread(this::receiveMessage).start();

        }

//    }

    private int panValue(String t) {
        return new Integer(t) %13+1;
    }

    //开始游戏
    private void startGame() {
        //移除规则介绍
        if (root != null && ruleView != null && backgroundView != null) {
            root.getChildren().remove(ruleView);
            backgroundView.setVisible(true);
        } else {
            System.out.println("组件未正确初始化！");
        }

        //发牌
        for (int i = 0; i < 4; i++) {
            Poker poker = pokerList.get(i);
            if (i % 2 == 0) {
                computer.add(poker);
                Tool.move(poker,cardPoint,new Point(75 + 30 * (computer.size() -1), 225));
            } else {
                player.add(poker);
                Tool.move(poker,cardPoint,new Point(510 + 30 * (player.size()-1), 225));
                poker.turnFront();
            }
            poker.toFront(); // 牌置顶
        }
        // 显示按钮
        get.setVisible(true);
        stop.setVisible(true);
        begin.setVisible(false);
        //显示玩家名
        playerName.setVisible(true);
        computerName.setVisible(true);
    }
    //玩家要牌
    private void getCard() {
        Poker poker = pokerList.get(index++);
        player.add(poker);
        Tool.move(poker, cardPoint, new Point(510 + (30 * (player.size()-1)), 225));
        poker.turnFront();
        poker.toFront(); // 牌置顶
        //玩家要牌后如果超过21，结束游戏
        if (Tool.isOver(player)) {
            for (Poker p : computer) {
                p.turnFront();//显示电脑牌
            }
            showAlert(Alert.AlertType.INFORMATION, "结果", null, "你的点数超过21点，你输了！");
            //开始按钮改为重新开始
            begin.setVisible(false);
            reset.setVisible(true);
            get.setVisible(false);
            stop.setVisible(false);
        }
        else { //玩家要牌后如果没超过21，轮到庄家要牌或停牌
            computer_getCard();
        }
    }
    //玩家停牌
    private void stopGetCard( ) {
        playerNeed = false;
        while (Tool.computerNeed(computer)) {//庄家继续要牌
            computer_getCard();
        }
        computerNeed = false; //庄家不需要牌了
        if (!isOver21_computer()) { //如果没超过21
            if (!playerNeed && !computerNeed) {//两边都不要牌了，判断胜负
                for (Poker p : computer) {
                    p.turnFront(); //显示电脑的牌
                }
                // 显示结果对话框
                String END = Tool.isWin(player, computer); //判断胜负
                showAlert(Alert.AlertType.INFORMATION, "结果", null, END);
                //开始按钮改为重新开始
                begin.setVisible(false);
                reset.setVisible(true);
                get.setVisible(false);
                stop.setVisible(false);
            }
        }
    }
    //庄家要牌
    private void computer_getCard() {
        PauseTransition pause = new PauseTransition(Duration.seconds(0.5));
        pause.setOnFinished(event -> {
            if (Tool.computerNeed(computer)) { //如果庄家还要牌
                Poker poker1 = pokerList.get(index++);
                computer.add(poker1);
                Tool.move(poker1, cardPoint, new Point(75 + (30 * (computer.size() - 1)), 225));
                poker1.toFront(); // 牌置顶
            } else {
                computerNeed = false;
            }
        });
        pause.play();
        isOver21_computer(); //判断庄家牌数是否大于21
    }
    //重置游戏
    private void resetGame() {
        pokerList.clear(); // 清空牌盒
        //清空玩家和电脑的牌
        player.clear();
        computer.clear();
        index = 4; // 重置牌的索引
        root.getChildren().removeAll();
        //初始化牌
        initializeComponents();
        initCard();
        startGame();
    }
    //判断庄家是否超过21点
    private boolean isOver21_computer() {
        if (Tool.isOver(computer)) {
            for (Poker p : computer) {
                p.turnFront();
            }
            showAlert(Alert.AlertType.INFORMATION, "结果", null, "庄家的点数超过21点，你赢了！");
            begin.setVisible(false);
            reset.setVisible(true);
            get.setVisible(false);
            stop.setVisible(false);
            return true;
        }
        return false;
    }
    //弹出警告
    private void showAlert(Alert.AlertType alertType, String title, String headerText, String contentText) {
        Alert alert = new Alert(alertType);
        alert.setTitle(title);
        alert.setHeaderText(headerText);
        alert.setContentText(contentText);
        alert.showAndWait();
    }
private String panduan(String a){
    if (Objects.equals(a.substring(0, 1), "♥")) {
        switch (a.substring(1)) {
            case "A":
                return "0";
            case "J":
                return "10";
            case "Q":
                return "11";
            case "K":
                return "12";
            default:
                return String.valueOf(new Integer(a.substring(1)) -1);
        }

    } else if (Objects.equals(a.substring(0, 1), "♣")) {
        switch (a.substring(1)) {
            case "A":
                return "13";
            case "J":
                return "23";
            case "Q":
                return "24";
            case "K":
                return "25";
            default:
                return String.valueOf(new Integer(a.substring(1)) +12);
        }
    } else if (Objects.equals(a.substring(0, 1), "♠")) {
        switch (a.substring(1)) {
            case "A":
                return "26";
            case "J":
                return "36";
            case "Q":
                return "37";
            case "K":
                return "38";
            default:
                return String.valueOf(new Integer(a.substring(1)) +25);
        }
    } else {
        switch (a.substring(1)) {
            case "A":
                return "39";
            case "J":
                return "49";
            case "Q":
                return "50";
            case "K":
                return "51";
            default:
                return String.valueOf(new Integer(a.substring(1)) +38);
        }
    }
}
    public static void main(String[] args) {
        launch(args);
    }
}